class AudioSpectrumAnalyzer {
    constructor() {
        this.audioContext = null;
        this.analyser = null;
        this.audioBuffer = null;
        this.source = null;
        this.canvas = document.getElementById('canvas');
        this.ctx = this.canvas.getContext('2d');
        this.isPlaying = false;
        this.isPaused = false;
        this.startTime = 0;
        this.pausedTime = 0;
        this.animationId = null;
        this.frequencyData = null;
        this.cachedSpectrumData = null;
        this.currentTime = 0;
        
        // UI元素
        this.playBtn = document.getElementById('playBtn');
        this.pauseBtn = document.getElementById('pauseBtn');
        this.stopBtn = document.getElementById('stopBtn');
        this.analyzeBtn = document.getElementById('analyzeBtn');
        this.audioFileInput = document.getElementById('audioFile');
        this.status = document.getElementById('status');
        this.fileInfo = document.getElementById('fileInfo');
        this.progressBar = document.getElementById('progressBar');
        
        this.initializeCanvas();
        this.bindEvents();
        this.initializeVisualizerSystem();
    }

    initializeCanvas() {
        const resizeCanvas = () => {
            const rect = this.canvas.getBoundingClientRect();
            this.canvas.width = rect.width * window.devicePixelRatio;
            this.canvas.height = rect.height * window.devicePixelRatio;
            this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
        };
        
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);
    }

    bindEvents() {
        this.audioFileInput.addEventListener('change', (e) => this.handleFileUpload(e));
        this.playBtn.addEventListener('click', () => this.play());
        this.pauseBtn.addEventListener('click', () => this.pause());
        this.stopBtn.addEventListener('click', () => this.stop());
        this.analyzeBtn.addEventListener('click', () => this.analyzeSpectrum());
    }

    async handleFileUpload(event) {
        const file = event.target.files[0];
        if (!file) return;

        this.updateStatus('正在加载音频文件...', 'loading');
        
        try {
            // 初始化AudioContext
            if (!this.audioContext) {
                this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
            }

            // 读取文件
            const arrayBuffer = await file.arrayBuffer();
            this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
            
            // 显示文件信息
            this.displayFileInfo(file, this.audioBuffer);
            
            // 启用控制按钮
            this.playBtn.disabled = false;
            this.analyzeBtn.disabled = false;
            
            this.updateStatus('音频文件加载成功！可以播放或分析频谱。');
            
            // 检查是否有缓存的频谱数据
            this.checkCachedSpectrum(file.name);
            
        } catch (error) {
            console.error('音频加载失败:', error);
            this.updateStatus('音频文件加载失败，请检查文件格式。', 'error');
        }
    }

    displayFileInfo(file, audioBuffer) {
        const duration = audioBuffer.duration.toFixed(2);
        const sampleRate = audioBuffer.sampleRate;
        const channels = audioBuffer.numberOfChannels;
        const size = (file.size / 1024 / 1024).toFixed(2);
        
        this.fileInfo.innerHTML = `
            <strong>文件信息：</strong><br>
            📁 文件名: ${file.name}<br>
            ⏱️ 时长: ${duration}秒<br>
            🔊 采样率: ${sampleRate}Hz<br>
            📡 声道数: ${channels}<br>
            💾 文件大小: ${size}MB
        `;
    }

    checkCachedSpectrum(fileName) {
        const cacheKey = `spectrum_${fileName}`;
        const cached = localStorage.getItem(cacheKey);
        if (cached) {
            this.cachedSpectrumData = JSON.parse(cached);
            this.updateStatus('发现缓存的频谱数据，播放时将使用增强动画！');
        }
    }

    async play() {
        if (!this.audioBuffer) return;

        try {
            if (this.audioContext.state === 'suspended') {
                await this.audioContext.resume();
            }

            // 停止当前播放
            this.stop();

            // 创建新的音频源
            this.source = this.audioContext.createBufferSource();
            this.source.buffer = this.audioBuffer;

            // 创建分析器
            this.analyser = this.audioContext.createAnalyser();
            this.analyser.fftSize = 2048;
            this.analyser.smoothingTimeConstant = 0.8;

            // 连接音频图
            this.source.connect(this.analyser);
            this.analyser.connect(this.audioContext.destination);

            // 初始化频谱数据数组
            this.frequencyData = new Uint8Array(this.analyser.frequencyBinCount);

            // 设置播放时间
            const offset = this.isPaused ? this.pausedTime : 0;
            this.startTime = this.audioContext.currentTime - offset;
            this.source.start(0, offset);

            this.isPlaying = true;
            this.isPaused = false;

            // 更新按钮状态
            this.playBtn.disabled = true;
            this.pauseBtn.disabled = false;
            this.stopBtn.disabled = false;

            // 开始可视化
            this.startVisualization();

            // 监听播放结束
            this.source.onended = () => {
                if (this.isPlaying) {
                    this.stop();
                }
            };

            this.updateStatus('正在播放...');

        } catch (error) {
            console.error('播放失败:', error);
            this.updateStatus('播放失败', 'error');
        }
    }

    pause() {
        if (!this.isPlaying || this.isPaused) return;

        this.source.stop();
        this.pausedTime = this.audioContext.currentTime - this.startTime;
        this.isPlaying = false;
        this.isPaused = true;

        this.playBtn.disabled = false;
        this.pauseBtn.disabled = true;

        this.stopVisualization();
        this.updateStatus('已暂停');
    }

    stop() {
        if (this.source) {
            this.source.stop();
            this.source = null;
        }

        this.isPlaying = false;
        this.isPaused = false;
        this.pausedTime = 0;

        this.playBtn.disabled = false;
        this.pauseBtn.disabled = true;
        this.stopBtn.disabled = true;

        this.stopVisualization();
        this.progressBar.style.width = '0%';
        this.updateStatus('已停止');
    }

    // 真正的FFT实现
    fft(signal) {
        const N = signal.length;
        if (N <= 1) return signal;

        // 递归FFT实现
        const even = [];
        const odd = [];
        for (let i = 0; i < N; i++) {
            if (i % 2 === 0) {
                even.push(signal[i]);
            } else {
                odd.push(signal[i]);
            }
        }

        const evenFFT = this.fft(even);
        const oddFFT = this.fft(odd);

        const result = new Array(N);
        for (let k = 0; k < N / 2; k++) {
            const t = {
                real: Math.cos(-2 * Math.PI * k / N) * oddFFT[k].real - Math.sin(-2 * Math.PI * k / N) * oddFFT[k].imag,
                imag: Math.sin(-2 * Math.PI * k / N) * oddFFT[k].real + Math.cos(-2 * Math.PI * k / N) * oddFFT[k].imag
            };

            result[k] = {
                real: evenFFT[k].real + t.real,
                imag: evenFFT[k].imag + t.imag
            };

            result[k + N / 2] = {
                real: evenFFT[k].real - t.real,
                imag: evenFFT[k].imag - t.imag
            };
        }

        return result;
    }

    // 将时域信号转换为频域的幅度谱
    getSpectrum(timeData) {
        // 确保数据长度是2的幂次
        const fftSize = 2048;
        const input = new Array(fftSize);
        
        for (let i = 0; i < fftSize; i++) {
            input[i] = {
                real: i < timeData.length ? timeData[i] : 0,
                imag: 0
            };
        }

        // 应用汉宁窗减少频谱泄露
        for (let i = 0; i < fftSize; i++) {
            const windowValue = 0.5 * (1 - Math.cos(2 * Math.PI * i / (fftSize - 1)));
            input[i].real *= windowValue;
        }

        // 执行FFT
        const fftResult = this.fft(input);

        // 计算幅度谱
        const spectrum = new Array(fftSize / 2);
        for (let i = 0; i < fftSize / 2; i++) {
            const real = fftResult[i].real;
            const imag = fftResult[i].imag;
            spectrum[i] = Math.sqrt(real * real + imag * imag);
        }

        return spectrum;
    }

    async analyzeSpectrum() {
        if (!this.audioBuffer) return;

        this.updateStatus('正在进行真实FFT频谱分析，请稍候...', 'loading');
        this.analyzeBtn.disabled = true;

        try {
            const channelData = this.audioBuffer.getChannelData(0);
            const sampleRate = this.audioBuffer.sampleRate;
            const fftSize = 2048;
            const hopSize = 512; // 窗口移动步长
            const frameCount = Math.floor((channelData.length - fftSize) / hopSize);
            
            const spectrumFrames = [];
            
            for (let frame = 0; frame < frameCount; frame++) {
                // 更新进度
                if (frame % 100 === 0) {
                    const progress = (frame / frameCount * 100).toFixed(1);
                    this.updateStatus(`正在分析频谱... ${progress}%`, 'loading');
                    
                    // 让浏览器有时间更新UI
                    await new Promise(resolve => setTimeout(resolve, 1));
                }

                const startSample = frame * hopSize;
                const timeSlice = channelData.slice(startSample, startSample + fftSize);
                
                // 执行真正的FFT
                const spectrum = this.getSpectrum(timeSlice);
                
                // 转换为与Web Audio API兼容的格式（0-255）
                const frequencyData = new Uint8Array(1024); // analyserNode.frequencyBinCount
                
                for (let i = 0; i < frequencyData.length; i++) {
                    // 对数缩放以匹配人耳感知
                    const magnitude = spectrum[i] || 0;
                    const db = 20 * Math.log10(magnitude + 1e-10); // 避免log(0)
                    const normalized = Math.max(0, Math.min(255, (db + 60) * 255 / 60)); // -60dB to 0dB映射到0-255
                    frequencyData[i] = normalized;
                }
                
                spectrumFrames.push(Array.from(frequencyData));
            }

            // 缓存频谱数据
            this.cachedSpectrumData = spectrumFrames;
            const fileName = this.audioFileInput.files[0].name;
            const cacheKey = `spectrum_${fileName}`;
            localStorage.setItem(cacheKey, JSON.stringify(spectrumFrames));

            this.updateStatus(`真实FFT频谱分析完成！共分析了 ${spectrumFrames.length} 帧数据并已缓存。`);

        } catch (error) {
            console.error('频谱分析失败:', error);
            this.updateStatus('频谱分析失败', 'error');
        } finally {
            this.analyzeBtn.disabled = false;
        }
    }

    startVisualization() {
        const draw = () => {
            if (!this.isPlaying) return;

            // 更新进度条
            this.currentTime = this.audioContext.currentTime - this.startTime;
            const progress = (this.currentTime / this.audioBuffer.duration) * 100;
            this.progressBar.style.width = `${Math.min(100, progress)}%`;

            // 获取实时频谱数据
            if (this.analyser) {
                this.analyser.getByteFrequencyData(this.frequencyData);
            }

            // 绘制可视化
            this.drawVisualization();

            this.animationId = requestAnimationFrame(draw);
        };

        draw();
    }

    stopVisualization() {
        if (this.animationId) {
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
        
        // 清空画布
        this.ctx.clearRect(0, 0, this.canvas.width / window.devicePixelRatio, this.canvas.height / window.devicePixelRatio);
    }

    initializeVisualizerSystem() {
        // 确保VisualizerManager类已加载
        if (typeof VisualizerManager === 'undefined') {
            console.error('VisualizerManager not loaded');
            return;
        }
        
        // 初始化可视化器管理系统
        this.visualizerManager = new VisualizerManager();
        this.visualizerManager.setCanvas(this.canvas);
        
        // 注册所有可视化器
        this.visualizerManager.registerFromGlobal();
        
        // 导出到全局以便选择器访问
        window.audioAnalyzer = this;
        
        // 设置全局管理器实例
        if (!window.visualizerManager) {
            window.visualizerManager = this.visualizerManager;
        }
        
        console.log('Visualizer system initialized', this.visualizerManager.getAvailableVisualizers());
    }

    drawVisualization() {
        if (!this.frequencyData) return;

        // 使用可视化器系统渲染，如果没有则使用默认渲染
        if (this.visualizerManager && this.visualizerManager.currentVisualizer) {
            // 获取缓存数据
            let cachedFrame = null;
            if (this.cachedSpectrumData) {
                const hopSize = 512;
                const sampleRate = this.audioBuffer ? this.audioBuffer.sampleRate : 44100;
                const frameRate = sampleRate / hopSize;
                const frameIndex = Math.floor(this.currentTime * frameRate);
                
                if (frameIndex >= 0 && frameIndex < this.cachedSpectrumData.length) {
                    cachedFrame = new Uint8Array(this.cachedSpectrumData[frameIndex]);
                }
            }
            
            // 使用可视化器渲染
            this.visualizerManager.render(this.frequencyData, cachedFrame, this.currentTime);
        } else {
            // 回退到默认可视化
            this.drawDefaultVisualization();
        }
    }

    drawDefaultVisualization() {
        const canvas = this.canvas;
        const ctx = this.ctx;
        const width = canvas.width / window.devicePixelRatio;
        const height = canvas.height / window.devicePixelRatio;

        // 清空画布
        ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
        ctx.fillRect(0, 0, width, height);

        if (!this.frequencyData) return;

        const barCount = 128;
        const barWidth = width / barCount;

        // 如果有缓存的频谱数据，使用增强动画
        if (this.cachedSpectrumData) {
            // 根据实际的帧率计算索引（基于hopSize）
            const hopSize = 512;
            const sampleRate = this.audioBuffer.sampleRate;
            const frameRate = sampleRate / hopSize; // 实际帧率
            const frameIndex = Math.floor(this.currentTime * frameRate);
            
            if (frameIndex < this.cachedSpectrumData.length) {
                const cachedFrame = this.cachedSpectrumData[frameIndex];
                this.drawEnhancedVisualization(cachedFrame, this.frequencyData, barWidth, height);
            } else {
                this.drawBasicVisualization(this.frequencyData, barWidth, height);
            }
        } else {
            this.drawBasicVisualization(this.frequencyData, barWidth, height);
        }
    }

    drawBasicVisualization(frequencyData, barWidth, height) {
        const ctx = this.ctx;
        const barCount = 128;

        for (let i = 0; i < barCount; i++) {
            const value = frequencyData[i] || 0;
            const barHeight = (value / 255) * height * 0.8;

            // 创建渐变色
            const gradient = ctx.createLinearGradient(0, height, 0, height - barHeight);
            gradient.addColorStop(0, `hsl(${240 + (i / barCount) * 120}, 100%, 50%)`);
            gradient.addColorStop(1, `hsl(${240 + (i / barCount) * 120}, 100%, 70%)`);

            ctx.fillStyle = gradient;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);

            // 添加发光效果
            ctx.shadowColor = `hsl(${240 + (i / barCount) * 120}, 100%, 50%)`;
            ctx.shadowBlur = 10;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);
            ctx.shadowBlur = 0;
        }
    }

    drawEnhancedVisualization(cachedFrame, realtimeData, barWidth, height) {
        const ctx = this.ctx;
        const barCount = 128;

        for (let i = 0; i < barCount; i++) {
            const realtimeValue = realtimeData[i] || 0;
            const cachedValue = cachedFrame[i] || 0;
            
            // 结合实时数据和缓存数据
            const combinedValue = Math.max(realtimeValue, cachedValue * 0.7);
            const barHeight = (combinedValue / 255) * height * 0.8;

            // 根据强度创建动态颜色
            const intensity = combinedValue / 255;
            const hue = 240 + (i / barCount) * 120 + intensity * 60;
            const saturation = 100;
            const lightness = 50 + intensity * 30;

            const gradient = ctx.createLinearGradient(0, height, 0, height - barHeight);
            gradient.addColorStop(0, `hsl(${hue}, ${saturation}%, ${lightness}%)`);
            gradient.addColorStop(0.5, `hsl(${hue}, ${saturation}%, ${lightness + 20}%)`);
            gradient.addColorStop(1, `hsl(${hue}, ${saturation}%, ${lightness + 40}%)`);

            ctx.fillStyle = gradient;
            
            // 主频谱条
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);

            // 添加粒子效果
            if (intensity > 0.5) {
                for (let j = 0; j < 3; j++) {
                    const particleY = height - barHeight - Math.random() * 50;
                    const particleX = i * barWidth + Math.random() * barWidth;
                    const particleSize = Math.random() * 3 + 1;
                    
                    ctx.fillStyle = `hsla(${hue}, 100%, 80%, ${0.5 + Math.random() * 0.5})`;
                    ctx.beginPath();
                    ctx.arc(particleX, particleY, particleSize, 0, Math.PI * 2);
                    ctx.fill();
                }
            }

            // 发光效果
            ctx.shadowColor = `hsl(${hue}, 100%, 60%)`;
            ctx.shadowBlur = 15 * intensity;
            ctx.fillStyle = gradient;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);
            ctx.shadowBlur = 0;

            // 添加反射效果
            const reflectionGradient = ctx.createLinearGradient(0, height, 0, height + 30);
            reflectionGradient.addColorStop(0, `hsla(${hue}, ${saturation}%, ${lightness}%, 0.3)`);
            reflectionGradient.addColorStop(1, `hsla(${hue}, ${saturation}%, ${lightness}%, 0)`);
            
            ctx.fillStyle = reflectionGradient;
            ctx.fillRect(i * barWidth, height, barWidth - 1, 30);
        }
    }

    updateStatus(message, type = 'normal') {
        this.status.innerHTML = message;
        this.status.className = type;
    }
}

// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
    new AudioSpectrumAnalyzer();
});
